import { Directive, Input, EmbeddedViewRef, ɵstringify as stringify } from '@angular/core';
import { TemplateRef, ViewContainerRef } from '@angular/core';
import { AuthService } from './auth.service';
import { ROLE_LIST, AUTH_LIST } from './role';


@Directive({
  // tslint:disable-next-line:directive-selector
  selector: '[szAcl]'
})
export class SZAclDirective {
  private thenTemplateRef: TemplateRef<any> = null;
  private thenViewRef: EmbeddedViewRef<any> = null;
  private elseTemplateRef: TemplateRef<any> = null;
  private elseViewRef: EmbeddedViewRef<any> = null;
  private isValid = false;

  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainerRef: ViewContainerRef,
    private authService: AuthService
  ) {
    this.thenTemplateRef = templateRef;
  }

  @Input('szAcl')
  set condition(aclList: string[]) {
    let roleList = [];
    aclList.forEach(aclItem => {
      let tempRole = ROLE_LIST[aclItem] || AUTH_LIST[aclItem];
      if (!Array.isArray(tempRole)) {
        tempRole = [tempRole];
      }
      roleList = [...tempRole];
    });
    console.log(roleList);
    this.isValid = this.authService.isAuthorized(roleList);
    this.updateView();
  }

  @Input('szAclElse')
  set conditionElse(templateRef: TemplateRef<any>) {
    assertTemplate('szAclElse', templateRef);
    this.elseTemplateRef = templateRef;
    this.elseViewRef = null;  // clear previous view if any.
    this.updateView();
  }

  private updateView() {
    if (this.isValid) {
      if (!this.thenViewRef) {
        this.viewContainerRef.clear();
        this.elseViewRef = null;
        if (this.thenTemplateRef) {
          this.thenViewRef = this.viewContainerRef.createEmbeddedView(this.thenTemplateRef);
        }
      }
    } else {
      if (!this.elseViewRef) {
        this.viewContainerRef.clear();
        this.thenViewRef = null;
        if (this.elseTemplateRef) {
          this.elseViewRef = this.viewContainerRef.createEmbeddedView(this.elseTemplateRef);
        }
      }
    }
  }
}

function assertTemplate(property: string, templateRef: TemplateRef<any> | null): void {
  const isTemplateRefOrNull = !!(!templateRef || templateRef.createEmbeddedView);
  if (!isTemplateRefOrNull) {
    throw new Error(`${property} must be a TemplateRef, but received '${stringify(templateRef)}'.`);
  }
}
